import React, { Component } from "react";
import Child from "./Child";
// import React, { PureComponent } from "react";
// 只有类组件可以有生命周期

// PureComponent的作用就是自动的判断组件的数据改变前后是否相同，从而自己决定是否要更新
// 相当于是代替了shouldComponentUpdate
class App extends Component {
  //! 1. 初始化阶段
  // constructor就是初始化阶段的生命周期
  // constructor是类的一个特殊的函数, 是构造函数被实例化的时候调用, 最先被调用的函数，只会被调用一次
  // constructor里面必须要先调用super函数，才能使用this
  // constructor还可以接受一个props参数, 可以将props的值作为state的初始值进行使用
  constructor(props) {
    super(props);
    console.log("constructor");
    // 定义state
    this.state = {
      count: 10,
      name: "zhangsan",
      age: props.age,
      list: [],
    };
    // 也可以定义ref和改变事件的this指向等
    // this.dom = createRef();
    // this.handleClick = this.handleClick.bind(this);
  }

  //! 2. 挂载阶段
  // componentWillMount表示的是挂载前，现在是被废弃了
  UNSAFE_componentWillMount() {
    console.log("componentWillMount");
    // 是可以修改数据的，但是没有必要
    // this.setState({
    //   count: 20,
    // });

    // 看起来可以在这里做数据请求
    // 不能在这里做数据请求
    // 16版本react新增了fiber算法
    // 当一个组件要进行渲染或者更新的时候，那么就会去加载文件，解析代码，执行生命周期，渲染页面等等
    // 如果组件非常大的时候，整个任务就会非常大。并且js是单线程和同步。所以会出现卡顿的情况。
    // fiber算法将大的任务进行了分片化，将大的任务分成了很多小的任务。
    // 每次一个小的任务执行中间就有机会去执行其他的任务，缓解卡顿的情况

    // 因为fiber算法会拆分代码,会有一定概率会使请求多次执行，影响性能
    // 只能当整个页面全部渲染结束了之后，才能做数据请求
    // fetch("http://www.pudge.wang:3080/api/mapdata")
    //   .then((response) => response.json())
    //   .then((res) => {
    //     console.log(res);
    //     this.setState({
    //       list: res.features,
    //     });
    //   });
  }

  // render也是挂载阶段的生命周期
  // render函数必须要有的，必须要返回一段html
  // 不能做数据请求，会做很多次
  render() {
    console.log("render");
    // 最常见的是做解构
    const { count, name } = this.state;
    // const {age} = this.props;

    // const className = cx({})
    return (
      <>
        <h2>react旧版生命周期(16.3版本之前)</h2>
        <p>count: {count}</p>
        <p>name: {name}</p>
        <Child count={count} />
        <ul>
          {this.state.list.map((item) => (
            <li key={item.properties.id}>
              {item.properties.name} - {item.properties.value}
            </li>
          ))}
        </ul>
      </>
    );
  }

  // 挂载结束后执行
  componentDidMount() {
    // 相当于vue的mounted
    // 这里什么都能做
    // 请求只能在这里做
    console.log("componentDidMount");
    setTimeout(() => {
      this.setState({
        count: 20,
      });
    }, 2000);

    // fetch("http://www.pudge.wang:3080/api/mapdata")
    //   .then((response) => response.json())
    //   .then((res) => {
    //     console.log(res);
    //     this.setState({
    //       list: res.features,
    //     });
    //   });
  }

  //! 更新阶段
  // 只有当数据发生改变的时候才会执行
  // shouldComponentUpdate必须要返回一个布尔值
  // 表示询问组件是否要更新
  // 用来做性能优化的
  shouldComponentUpdate(nextProps, nextState) {
    // 需要去比较数据改变前后的值是否一样
    console.log("shouldComponentUpdate");
    // return true;
    // if (nextState.count === this.state.count) {
    //   return false;
    // } else {
    //   return true;
    // }
    return nextState.count !== this.state.count;
  }

  // 更新前
  // 也是被废弃了
  // 相当于vue的beforeUpdate, 做不了什么事情
  UNSAFE_componentWillUpdate() {
    console.log("componentWillUpdate");
  }

  // 数据更新后执行
  // 不能在更新后修改数据，会导致死循环
  componentDidUpdate() {
    console.log("componentDidUpdate");
    // this.setState((prevState) => {
    //   return {
    //     count: prevState.count + 1,
    //   };
    // });
  }

  //! 销毁阶段
  componentWillUnmount() {
    // 需要去手动关闭定时器, 关闭websocket长连接, js的事件监听addEventListener
    // 清除一些图表和地图等第三方插件的实例
    console.log("componentWillUnmount");
  }
}

export default App;
